package com.ld.poetry.controller;


import com.baomidou.mybatisplus.extension.conditions.query.LambdaQueryChainWrapper;
import com.ld.poetry.aop.LoginCheck;
import com.ld.poetry.config.PoetryResult;
import com.ld.poetry.constants.CommonConst;
import com.ld.poetry.dao.*;
import com.ld.poetry.entity.*;
import com.ld.poetry.service.WebInfoService;
import com.ld.poetry.utils.*;
import com.ld.poetry.utils.cache.PoetryCache;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;

import java.time.LocalDateTime;
import java.time.LocalTime;
import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 * 网站信息表 前端控制器
 * </p>
 *
 * @author sara
 * @since 2021-09-14
 */
@RestController
@RequestMapping("/webInfo")
public class WebInfoController {

    @Value("${store.type}")
    private String defaultType;

    @Autowired
    private WebInfoService webInfoService;

    @Autowired
    private HistoryInfoMapper historyInfoMapper;

    @Autowired
    private CommonQuery commonQuery;


    /**
     * 更新网站信息
     * 
     * 功能说明：
     * 1. 更新网站的基本配置信息
     * 2. 更新缓存中的网站信息
     * 3. 设置默认存储类型
     * 
     * 请求参数：
     * @param webInfo 网站信息对象，包含需要更新的配置信息
     * 
     * 返回结果：
     * @return PoetryResult<WebInfo> 操作结果，成功时返回空对象
     * 
     * 处理步骤：
     * 1. 更新数据库中的网站信息
     * 2. 查询最新的网站信息
     * 3. 设置默认存储类型
     * 4. 更新缓存中的网站信息
     * 
     * 注意事项：
     * 1. 需要管理员权限
     * 2. 更新后会自动刷新缓存
     * 3. 默认存储类型从配置文件中读取
     */
    @LoginCheck(0)
    @PostMapping("/updateWebInfo")
    public PoetryResult<WebInfo> updateWebInfo(@RequestBody WebInfo webInfo) {
        // 更新数据库中的网站信息
        webInfoService.updateById(webInfo);

        // 查询最新的网站信息
        LambdaQueryChainWrapper<WebInfo> wrapper = new LambdaQueryChainWrapper<>(webInfoService.getBaseMapper());
        List<WebInfo> list = wrapper.list();
        
        // 如果查询结果不为空，更新缓存
        if (!CollectionUtils.isEmpty(list)) {
            // 设置默认存储类型
            list.get(0).setDefaultStoreType(defaultType);
            // 更新缓存中的网站信息
            PoetryCache.put(CommonConst.WEB_INFO, list.get(0));
        }
        
        // 返回成功结果
        return PoetryResult.success();
    }


    /**
     * 获取网站信息
     * 
     * 功能说明：
     * 1. 从缓存中获取网站的基本配置信息
     * 2. 过滤敏感配置信息（随机头像、随机名称、看板娘配置）
     * 3. 获取网站访问统计信息
     * 
     * 请求参数：
     * 无
     * 
     * 返回结果：
     * @return PoetryResult<WebInfo> 网站信息对象，包含基本配置和访问统计
     * 
     * 处理步骤：
     * 1. 从缓存获取网站信息
     * 2. 创建新的结果对象
     * 3. 复制基本属性
     * 4. 过滤敏感配置
     * 5. 获取访问统计信息
     * 6. 返回处理结果
     * 
     * 注意事项：
     * 1. 不需要登录权限
     * 2. 敏感配置信息会被过滤
     * 3. 访问统计信息从缓存中获取
     */
    @GetMapping("/getWebInfo")
    public PoetryResult<WebInfo> getWebInfo() {
        // 从缓存获取网站信息
        WebInfo webInfo = (WebInfo) PoetryCache.get(CommonConst.WEB_INFO);
        
        // 如果缓存中存在网站信息
        if (webInfo != null) {
            // 创建新的结果对象
            WebInfo result = new WebInfo();
            
            // 复制基本属性
            BeanUtils.copyProperties(webInfo, result);
            
            // 过滤敏感配置信息
            result.setRandomAvatar(null);
            result.setRandomName(null);
            result.setWaifuJson(null);

            // 获取访问统计信息
            webInfo.setHistoryAllCount(((Long) ((Map<String, Object>) PoetryCache.get(CommonConst.IP_HISTORY_STATISTICS)).get(CommonConst.IP_HISTORY_COUNT)).toString());
            webInfo.setHistoryDayCount(Integer.toString(((List<Map<String, Object>>) ((Map<String, Object>) PoetryCache.get(CommonConst.IP_HISTORY_STATISTICS)).get(CommonConst.IP_HISTORY_HOUR)).size()));
            
            // 返回处理结果
            return PoetryResult.success(result);
        }
        
        // 缓存中不存在网站信息，返回空结果
        return PoetryResult.success();
    }

    /**
     * 获取网站统计信息
     * 
     * 功能说明：
     * 1. 获取网站访问统计信息
     * 2. 统计今日和昨日的访问数据
     * 3. 统计访问用户的地区分布
     * 
     * 请求参数：
     * 无
     * 
     * 返回结果：
     * @return PoetryResult<Map<String, Object>> 统计信息对象，包含访问数据和用户信息
     * 
     * 处理步骤：
     * 1. 获取历史访问统计缓存
     * 2. 查询今日访问记录
     * 3. 统计访问数据
     * 4. 处理用户信息
     * 5. 统计地区分布
     * 6. 返回处理结果
     * 
     * 注意事项：
     * 1. 需要管理员权限
     * 2. 数据从缓存和数据库获取
     * 3. 包含敏感信息，需要权限控制
     */
    @LoginCheck(0)
    @GetMapping("/getHistoryInfo")
    public PoetryResult<Map<String, Object>> getHistoryInfo() {
        // 创建返回结果对象
        Map<String, Object> result = new HashMap<>();

        // 获取历史访问统计缓存
        Map<String, Object> history = (Map<String, Object>) PoetryCache.get(CommonConst.IP_HISTORY_STATISTICS);
        
        // 查询今日访问记录
        List<HistoryInfo> infoList = new LambdaQueryChainWrapper<>(historyInfoMapper)
                .select(HistoryInfo::getIp, HistoryInfo::getUserId, HistoryInfo::getNation, HistoryInfo::getProvince, HistoryInfo::getCity)
                .ge(HistoryInfo::getCreateTime, LocalDateTime.now().with(LocalTime.MIN))
                .list();

        // 设置历史统计信息
        result.put(CommonConst.IP_HISTORY_PROVINCE, history.get(CommonConst.IP_HISTORY_PROVINCE));
        result.put(CommonConst.IP_HISTORY_IP, history.get(CommonConst.IP_HISTORY_IP));
        result.put(CommonConst.IP_HISTORY_COUNT, history.get(CommonConst.IP_HISTORY_COUNT));
        
        // 获取昨日访问数据
        List<Map<String, Object>> ipHistoryCount = (List<Map<String, Object>>) history.get(CommonConst.IP_HISTORY_HOUR);
        
        // 统计昨日独立IP数
        result.put("ip_count_yest", ipHistoryCount.stream().map(m -> m.get("ip")).distinct().count());
        
        // 处理昨日访问用户信息
        result.put("username_yest", ipHistoryCount.stream().map(m -> {
            Object userId = m.get("user_id");
            if (userId != null) {
                User user = commonQuery.getUser(Integer.valueOf(userId.toString()));
                if (user != null) {
                    Map<String, String> userInfo = new HashMap<>();
                    userInfo.put("avatar", user.getAvatar());
                    userInfo.put("username", user.getUsername());
                    return userInfo;
                }
            }
            return null;
        }).filter(Objects::nonNull).collect(Collectors.toList()));
        
        // 统计今日独立IP数
        result.put("ip_count_today", infoList.stream().map(HistoryInfo::getIp).distinct().count());
        
        // 处理今日访问用户信息
        result.put("username_today", infoList.stream().map(m -> {
            Integer userId = m.getUserId();
            if (userId != null) {
                User user = commonQuery.getUser(userId);
                if (user != null) {
                    Map<String, String> userInfo = new HashMap<>();
                    userInfo.put("avatar", user.getAvatar());
                    userInfo.put("username", user.getUsername());
                    return userInfo;
                }
            }
            return null;
        }).filter(Objects::nonNull).collect(Collectors.toList()));

        // 统计今日地区访问分布
        List<Map<String, Object>> list = infoList.stream()
                .map(HistoryInfo::getProvince).filter(Objects::nonNull)
                .collect(Collectors.groupingBy(m -> m, Collectors.counting()))
                .entrySet().stream()
                .map(entry -> {
                    HashMap<String, Object> map = new HashMap<>();
                    map.put("province", entry.getKey());
                    map.put("num", entry.getValue());
                    return map;
                })
                .sorted((o1, o2) -> Long.valueOf(o2.get("num").toString()).compareTo(Long.valueOf(o1.get("num").toString())))
                .collect(Collectors.toList());

        // 设置今日地区访问分布
        result.put("province_today", list);

        // 返回统计结果
        return PoetryResult.success(result);
    }

    /**
     * 获取赞赏用户列表
     * 
     * 功能说明：
     * 1. 获取所有赞赏过网站的用户信息
     * 2. 返回用户的基本信息（头像、用户名等）
     * 
     * 请求参数：
     * 无
     * 
     * 返回结果：
     * @return PoetryResult<List<User>> 赞赏用户列表
     * 
     * 处理步骤：
     * 1. 调用通用查询服务获取赞赏用户
     * 2. 返回用户列表
     * 
     * 注意事项：
     * 1. 不需要登录权限
     * 2. 返回用户基本信息
     * 3. 数据从数据库获取
     */
    @GetMapping("/getAdmire")
    public PoetryResult<List<User>> getAdmire() {
        // 调用通用查询服务获取赞赏用户列表
        return PoetryResult.success(commonQuery.getAdmire());
    }

    /**
     * 获取看板娘配置信息
     * 
     * 功能说明：
     * 1. 获取网站看板娘的配置信息
     * 2. 返回JSON格式的配置数据
     * 3. 支持自定义看板娘设置
     * 
     * 请求参数：
     * 无
     * 
     * 返回结果：
     * @return String JSON格式的看板娘配置信息，如果未配置则返回空JSON对象
     * 
     * 处理步骤：
     * 1. 从缓存获取网站信息
     * 2. 检查看板娘配置是否存在
     * 3. 返回配置信息或默认值
     * 
     * 注意事项：
     * 1. 不需要登录权限
     * 2. 配置信息从缓存获取
     * 3. 未配置时返回空JSON对象
     */
    @GetMapping("/getWaifuJson")
    public String getWaifuJson() {
        // 从缓存获取网站信息
        WebInfo webInfo = (WebInfo) PoetryCache.get(CommonConst.WEB_INFO);
        
        // 检查看板娘配置是否存在且不为空
        if (webInfo != null && StringUtils.hasText(webInfo.getWaifuJson())) {
            // 返回看板娘配置信息
            return webInfo.getWaifuJson();
        }
        
        // 未配置时返回空JSON对象
        return "{}";
    }
}

